use std::collections::HashMap;

#[derive(Debug, Clone)]
pub struct CookieStore {
    pub cookies: HashMap<String, String>,
}

/// cookies解析器
/// 使用方法
/// ```rust
/// cookies_str.parse::<CookieStore>()
/// ```
impl CookieStore {
    pub fn new() -> Self {
        Self {
            cookies: HashMap::new(),
        }
    }
    pub fn set_cookies(&mut self, name: String, value: String) -> Option<String> {
        self.cookies.insert(name, value)
    }
    pub fn to_string(&self) -> String {
        self.cookies
            .iter()
            .map(|(k, v)| format!("{}={}", k, v))
            .collect::<Vec<String>>()
            .join(";")
    }
    pub fn to_python_dict(&self) -> String {
        let body = self
            .cookies
            .iter()
            .map(|(k, v)| format!("    \"{k}\": \"{v}\""))
            .collect::<Vec<_>>()
            .join(",\n");
        format!("cookies = {{\n{}\n}}\n", body)
    }
    pub fn to_rust_hashmap(&self) -> String {
        let body = self
            .cookies
            .iter()
            .map(|(k, v)| format!("        \"{k}\"=> \"{v}\""))
            .collect::<Vec<_>>()
            .join(",\n");
        format!("let cookies = hashmap! {{\n{}\n}};\n", body)
    }
}

impl std::str::FromStr for CookieStore {
    type Err = String;
    fn from_str(s: &str) -> Result<Self, Self::Err> {
        let mut store = CookieStore::new();
        for cookie in s.split(";") {
            let parts: Vec<&str> = cookie.trim().split("=").collect();
            if parts.len() == 2 {
                store.set_cookies(parts[0].to_string(), parts[1].to_string());
            } else {
                return Err("cookie解析失败！".to_string());
            }
        }
        Ok(store)
    }
}
